home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2a.lha / p4-1.2a / lib / p4_rm.c < prev    next >
C/C++ Source or Header  |  1992-10-19  |  12KB  |  412 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. /*
  5.   Defining REDIRECT_OUTPUT allows you to redirect output from
  6.   processes as follows.
  7.   Defining OUT_TO_TERM tty allows you to redirect the
  8.   output from various processes to separate windows.
  9.   */
  10.  
  11. #if defined(REDIRECT_OUTPUT)
  12. #if defined(OUT_TO_TERM)
  13. #define P4_OUTFILE "/dev/ttyp4"
  14. #else
  15. #define P4_OUTFILE "/u/rbutler/p4/tests/out"
  16. #endif
  17. #endif
  18.  
  19. static int rm_num;
  20.  
  21. int rm_start(argc, argv)
  22. int *argc;
  23. char **argv;
  24. {
  25.     int bm_fd, bm_port;
  26.     char *s,*bm_host;
  27.     extern char whoami[];
  28.     struct net_initial_handshake hs;
  29.     struct slave_listener_msg lmsg;
  30.     struct bm_rm_msg msg;
  31.     int type, rc, i, numslaves;
  32.     struct p4_global_data *g;
  33.     char outfile[128];
  34.  
  35.     trap_sig_errs();         /* Errors can happen any time */
  36.  
  37.     sprintf(whoami, "rm_%d", getpid());
  38.     p4_dprintfl(20,"remote master starting\n");
  39.  
  40. #if defined(REDIRECT_OUTPUT)
  41.     freopen(P4_OUTFILE, "w", stdout);
  42.     freopen(P4_OUTFILE, "w", stderr);
  43. #endif
  44.  
  45.     if (*argc < 4)
  46.     p4_error("Invalid arguments to remote_master", *argc);
  47.  
  48.     bm_host = argv[1];
  49.     bm_port = atoi(argv[2]);
  50.  
  51.     bm_fd = net_conn_to_listener(bm_host, bm_port, 5);
  52.     if (bm_fd < 0)
  53.     p4_error("rm_start: net_conn_to_listener failed", bm_port);
  54.  
  55.     net_recv(bm_fd, &hs, sizeof(hs));
  56.     hs.pid = (int) htonl(getpid());
  57.     net_send(bm_fd, &hs, sizeof(hs), FALSE);
  58.  
  59. #   ifdef SYSV_IPC
  60.     sysv_num_shmids = 0;
  61.     sysv_shmid[0]  = -1;
  62.     sysv_semid0 = init_sysv_semset(0);
  63. #   endif
  64.  
  65.     /* Get the initialization information from the bm */
  66.  
  67.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  68.     if (rc == PRECV_EOF)
  69.     p4_error("rm_start: got EOF on net_recv", bm_fd);
  70.     type = p4_n_to_i(msg.type);
  71.     if (type != INITIAL_INFO)
  72.     p4_error("rm_start: unknown type, expecting INITIAL_INFO, type=", type);
  73.     if (strcmp(msg.version,p4_version()) != 0)
  74.     {
  75.     p4_dprintf("my version is %s\n",p4_version());
  76.     p4_error("version does not match master \n",0);
  77.     }
  78.  
  79.     if ((s = (char *) rindex(msg.pgm,'/'))  ==  NULL)
  80.     {
  81.     p4_dprintf("my fullpathname is invalid: %s\n",msg.pgm);
  82.     p4_error("fullpathname is invalid \n",0);
  83.     }
  84.     else
  85.     {
  86.     *s = '\0';  /* chg to directory name only */
  87.     chdir(msg.pgm);
  88.     }
  89.  
  90.     globmemsize = p4_n_to_i(msg.memsize);
  91.     logging_flag = p4_n_to_i(msg.logging_flag);
  92.     if (logging_flag)
  93.     ALOG_ENABLE;
  94.     else
  95.     ALOG_DISABLE;
  96.  
  97.     MD_initmem(globmemsize);
  98.     alloc_global();  /* sets p4_global */
  99.     g = p4_global;
  100.     p4_local = alloc_local_rm();
  101.     g->local_communication_only = FALSE;
  102.     g->num_in_proctable = p4_n_to_i(msg.numinproctab);
  103.     numslaves = p4_n_to_i(msg.numslaves);
  104.     rm_num = p4_n_to_i(msg.rm_num);
  105.     debug_level = p4_n_to_i(msg.debug_level);
  106.     strcpy(outfile, msg.outfile);
  107.     strcpy(p4_global->application_id, msg.application_id);
  108.     p4_dprintfl(90, "got numslaves=%d outfile=%s rm_num=%d dbglvl=%d appid=%s\n",
  109.         numslaves, outfile, rm_num, debug_level, msg.application_id);
  110.  
  111.     MD_initenv();
  112.     usc_init();
  113.  
  114.     if (*outfile)
  115.     {
  116.     freopen(outfile, "w", stdout);
  117.     freopen(outfile, "w", stderr);
  118.     }
  119.  
  120.     SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  121.     p4_lock(&g->slave_lock);
  122.     create_rm_processes(numslaves, bm_fd);
  123.  
  124.     /* Grab the whole proc table from the bm */
  125.     p4_dprintfl(90, "receiving proc table\n");
  126.     receive_proc_table(bm_fd);
  127.  
  128.     /* let local slaves use proctable to identify themselves */
  129.     p4_unlock(&g->slave_lock);
  130.  
  131.     sprintf(whoami, "rm_%d_%d", rm_num, getpid());
  132.     p4_local->my_id = p4_get_my_id_from_proc();
  133.  
  134.     p4_global->low_cluster_id = 
  135.     p4_local->my_id - p4_global->proctable[p4_local->my_id].slave_idx;
  136.     p4_global->hi_cluster_id = 
  137.     p4_global->low_cluster_id + p4_global->local_slave_count;
  138.  
  139.     setup_conntab();
  140.  
  141.     if (p4_local->conntab[0].type == CONN_REMOTE_SWITCH)
  142.     {
  143.     p4_local->conntab[0].switch_port = p4_global->proctable[0].switch_port;
  144.     p4_local->conntab[0].port = bm_fd;
  145.     }
  146.     else if (p4_local->conntab[0].type == CONN_REMOTE_NON_EST)
  147.     {
  148.     p4_local->conntab[0].type = CONN_REMOTE_EST;
  149.     p4_local->conntab[0].port = bm_fd;
  150.     p4_local->conntab[0].same_data_rep =
  151.         same_data_representation(p4_local->my_id,0);
  152.     }
  153.     else
  154.     {
  155.     p4_error("rm_start: invalid conn type in conntab ",
  156.          p4_local->conntab[0].type);
  157.     }
  158.  
  159.     sprintf(whoami, "p%d_%d", p4_get_my_id(), getpid());
  160.  
  161.  
  162. #if defined(IPSC860)  ||  defined(CM5)
  163.     for (i = 1; i < numslaves; i++)
  164.     {
  165. #       if defined(IPSC860)
  166.     csend((long) INITIAL_INFO, &msg, (long) sizeof(struct bm_rm_msg), 
  167.               (long) i, (long) NODE_PID);
  168.     csend((long) INITIAL_INFO, p4_global->proctable, 
  169.               (long) sizeof(p4_global->proctable), (long) i, (long) NODE_PID);
  170. #       endif
  171. #       if defined(CM5)
  172.     CMMD_send_noblock(i, INITIAL_INFO,  &msg,sizeof(struct bm_rm_msg));
  173.     CMMD_send_noblock(i, INITIAL_INFO,  p4_global->proctable, 
  174.                           sizeof(p4_global->proctable));
  175. #       endif
  176.     }
  177. #endif
  178.  
  179.     /* 
  180.        sync with local slaves thus insuring that they have the proctable before 
  181.        syncing with bm (this keeps bm and its slaves  from interrupting the local 
  182.        processes too early; then re-sync with local slaves (thus permitting them to 
  183.        interrupt remotes)
  184.     */
  185.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  186.     
  187.     msg.type = p4_i_to_n(SYNC_MSG);
  188.     net_send(bm_fd, &msg, sizeof(msg), FALSE);
  189.     msg.type = -1;  /* reset to verify type received next */
  190.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  191.     type = p4_n_to_i(msg.type);
  192.     if (type != SYNC_MSG)
  193.     p4_error("rm_start: unknown type, expecting SYNC_MSG, type=", type);
  194.     
  195.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  196.  
  197.     return(0);
  198. }
  199.  
  200.  
  201. P4VOID create_rm_processes(nslaves, bm_fd)
  202. int nslaves;
  203. int bm_fd;
  204. {
  205.     struct p4_global_data *g = p4_global;
  206.     struct listener_data *l;
  207.     int end_1, end_2, slave_pid, listener_pid;
  208.     int slave_idx, listener_port, listener_fd;
  209.     char rm_host[100];
  210.     int i, rm_switch_port;
  211.     struct bm_rm_msg bm_msg;
  212.  
  213. #   if !defined(IPSC860)  &&  !defined(CM5)
  214.     if (nslaves > P4_MAX_MSG_QUEUES)
  215.     p4_error("create_rm_processes: more slaves than msg queues \n", nslaves);
  216. #   endif
  217.  
  218.     /*
  219.      * Allocate the listener's local data area, since this process will
  220.      * eventually become the listener.
  221.      */
  222.  
  223.     l = listener_info = alloc_listener_info();
  224.  
  225.     net_setup_anon_listener(10, &listener_port, &listener_fd);
  226.  
  227.     p4_dprintfl(70, "created listener on port %d fd %d\n", listener_port,
  228.         listener_fd);
  229.  
  230.     /* Send off the listener info to the bm */
  231.     bm_msg.type = p4_i_to_n(REMOTE_LISTENER_INFO);
  232.     bm_msg.port = p4_i_to_n(listener_port);
  233.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  234.  
  235.     rm_host[0] = '\0';
  236.     get_qualified_hostname(rm_host);
  237.     rm_switch_port = getswport(rm_host);
  238.  
  239.     /* Send my info to the bm */
  240.     bm_msg.type = p4_i_to_n(REMOTE_MASTER_INFO);
  241.     bm_msg.slave_idx = p4_i_to_n(0);
  242.     bm_msg.slave_pid = p4_i_to_n(getpid());
  243.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  244.     strcpy(bm_msg.host_name,rm_host);
  245.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  246.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  247.  
  248.     g->local_slave_count = 0;
  249.  
  250. #   ifdef TCMP
  251.     tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  252. #   endif
  253.  
  254. #   if defined(IPSC860)  ||  defined(CM5)
  255.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  256.     {
  257. #       if defined(IPSC860)
  258.     crecv(INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg));
  259. #       endif
  260. #       if defined(CM5)
  261.         CMMD_receive(CMMD_ANY_NODE, INITIAL_INFO, (void *) &bm_msg, 
  262.                      sizeof(struct bm_rm_msg));
  263. #       endif
  264.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  265.     g->local_slave_count++;
  266.     }
  267. #   else
  268.  
  269.     get_pipe(&end_1, &end_2);
  270.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  271.     {
  272.     p4_dprintfl(20,"remote master creating local slave %d\n",slave_idx);
  273.             
  274.     slave_pid = fork_p4();
  275.     if (slave_pid)
  276.         p4_dprintfl(10,"remote master created local slave %d\n",slave_idx);
  277.     if (slave_pid == 0)
  278.     {
  279.         /* In the slave process */
  280.  
  281.         sprintf(whoami, "rm_s_%d_%d_%d", rm_num, slave_idx, getpid());
  282.  
  283.         close(listener_fd);
  284.         p4_local = alloc_local_slave();
  285.         p4_local->listener_fd = end_1;
  286.         close(end_2);
  287.  
  288.             SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  289.  
  290.  
  291.         /* hang for a valid proctable */
  292.         p4_lock(&g->slave_lock);
  293.         p4_unlock(&g->slave_lock);
  294.  
  295.         p4_local->my_id = p4_get_my_id_from_proc();
  296.         sprintf(whoami, "p%d_%d", p4_get_my_id(), getpid());
  297.         setup_conntab();
  298.         usc_init();
  299.  
  300. #           ifdef TCMP
  301.             tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  302. #           endif
  303.  
  304.         /* 
  305.            sync with local master twice: once to make sure all slaves 
  306.            have got proctable, and second after the master has synced bm
  307.         */
  308.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  309.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  310.  
  311.         p4_dprintfl(20, "remote process starting\n");
  312.             ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  313.             ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  314.         slave();
  315.             ALOG_LOG(p4_local->my_id,END_USER,0,"");
  316.             ALOG_OUTPUT;
  317.         p4_dprintfl(20, "remote process exiting\n");
  318.  
  319.         exit(0);
  320.     }
  321.  
  322.     /* Send off the slave info to the bm */
  323.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO);
  324.     bm_msg.slave_idx = p4_i_to_n(slave_idx);
  325.     bm_msg.slave_pid = p4_i_to_n(slave_pid);
  326.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  327.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  328.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  329.  
  330.     g->local_slave_count++;
  331.     }
  332. #endif
  333.  
  334.     /* Send the end message to the bm */
  335.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO_END);
  336.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  337.  
  338.     /*
  339.      * Done creating slaves. Now fork off the listener .. we've already
  340.      * created the socket and bound a port to it
  341.      */
  342.  
  343. #   if !defined(IPSC860)  &&  !defined(CM5)
  344.     g->listener_port = listener_port;
  345.     p4_local->listener_fd = end_1;
  346.     listener_pid = fork_p4();
  347.     if (listener_pid == 0)
  348.     {
  349.     /* Inside listener */
  350.     sprintf(whoami, "rm_l_%d_%d", rm_num, getpid());
  351.     p4_dprintfl(70, "inside listener pid %d\n", getpid());
  352.     p4_local = alloc_local_listener();
  353.     l->listening_fd = listener_fd;
  354.     l->slave_fd = end_2;
  355.     close(end_1);
  356.     listener();
  357.     exit(0);
  358.     }
  359.  
  360.     /* Else we're still in the remote master */
  361.  
  362.     p4_dprintfl(70, "created listener pid %d\n", listener_pid);
  363.     /* We need to close the fds from the listener setup */
  364.     close(listener_fd);
  365.     close(end_2);
  366.     g->listener_pid = listener_pid;
  367. #   endif
  368. }
  369.  
  370.  
  371. P4VOID receive_proc_table(bm_fd)
  372. int bm_fd;
  373. {
  374.     P4BOOL done;
  375.     struct bm_rm_msg msg;
  376.     int type;
  377.     int port, unix_id, slave_idx, group_id;
  378.     int switch_port;
  379.  
  380.     p4_dprintfl(90, "receive_proc_table\n");
  381.     for (done = FALSE; !done;)
  382.     {
  383.     if (net_recv(bm_fd, &msg, sizeof(msg)) == PRECV_EOF)
  384.         p4_error("recv_proc_table: got net_send_eof", bm_fd);
  385.  
  386.     type = p4_n_to_i(msg.type);
  387.     switch (type)
  388.     {
  389.       case PROC_TABLE_ENTRY:
  390.         group_id = p4_n_to_i(msg.group_id);
  391.         port = p4_n_to_i(msg.port);
  392.         unix_id = p4_n_to_i(msg.unix_id);
  393.         slave_idx = p4_n_to_i(msg.slave_idx);
  394.         switch_port = p4_n_to_i(msg.switch_port);
  395.         p4_dprintfl(90, "got entry gid=%d host=%s port=%d unix_id=%d slave_idx=%d switch_port=%d\n",
  396.             group_id,msg.host_name,port,unix_id,slave_idx,switch_port);
  397.         /* remote master loading proctable from big master */
  398.         install_in_proctable(group_id, port, unix_id, msg.host_name,
  399.                  slave_idx, msg.machine_type, switch_port);
  400.         break;
  401.  
  402.       case PROC_TABLE_END:
  403.         done = TRUE;
  404.         break;
  405.  
  406.       default:
  407.         p4_dprintf("receive_proc_table: got invalid message type %d\n", type);
  408.         break;
  409.     }
  410.     }
  411. }
  412.